<template>
  <div class="container" style="padding: 0px;width: 70%">
    <template v-if="props.checkType=='multiple'">
      <el-dialog v-model="visible" width="65%" :fullscreen="true" style="width: 70%" :title="props.title"
                 destroy-on-close
                 :before-close="close">
        <template #header>
          <div class="container" style="padding: 0px">
            <el-row :gutter="10" style="margin-bottom: 15px;">
              <span role="heading" class="el-dialog__title">{{ props.title }}</span>
            </el-row>
            <el-form :model="pageDto" ref="queryForm" :inline="true" v-show="showSearch"
                     label-width="68px">
              <slot v-bind="pageDto" name="pre-exactSearchForm">
                <!--        额外的搜索条件项-->
              </slot>
              <el-form-item v-for="(column,index) in searchformList" :key="index" :label="column.label"
                            :prop="column.index">
                <!--        如果是字典类型-->
                <template v-if="column.type=='dict'">
                  <el-select v-model="pageDto[column.index]"
                             :placeholder="'请选择'+column.label"
                             clearable>
                    <el-option
                        v-for="dict in dict(column.dictkey)"
                        :key="dict.value"
                        :label="dict.label"
                        :value="dict.value"
                    />
                  </el-select>
                </template>
                <template v-else>
                  <el-input
                      v-model="pageDto[column.index]"
                      :type="column.dataType?column.dataType:'text'"
                      :placeholder="'请输入'+column.label"
                      clearable
                      @keyup.enter.native="handleQuery"
                  />
                </template>

              </el-form-item>
              <slot name="exactSearchForm">
                <!--        额外的搜索条件项-->
              </slot>
              <el-form-item>
                <el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
                <el-button icon="RefreshRight" @click="resetQuery">重置</el-button>
              </el-form-item>
            </el-form>
            <el-row :gutter="10" style="margin-bottom: 8px;">
              <right-toolbar v-model:showSearch="showSearch" v-show="props.rightToolbar" @queryTable="handleQuery"
              ></right-toolbar>
            </el-row>
          </div>
        </template>
        <div style="height: 320px">
          <el-scrollbar style="height:100%">
            <el-table
                :data="tableData"
                class="table"
                ref="multipleTable"
                v-loading="listLoading"
                header-cell-class-name="table-header"
                @selection-change="handleSelectionChange"
            >
              <template slot="empty">
                <el-empty description="暂无数据"></el-empty>
              </template>
              <el-table-column type="selection" width="55" align="center"></el-table-column>
              <template v-for="(column,index) in columns" :key="index">
                <el-table-column :prop="column.index" :width="column.hasOwnProperty('width')?column.width:''"
                                 v-if="column.visible||!column.hasOwnProperty('visible')"
                                 :label="column.label" align="center">
                  <template v-slot="scope" v-if="column.type!='opt'">
                    <template v-if="column.type!='dict'">
                      <slot v-bind="scope" :name="column.index">
                        {{ scope.row[column.index] }}
                      </slot>
                    </template>
                    <template v-else>
                      <dict-tag :options="dict(column.dictkey)" :value="scope.row[column.index]"/>
                    </template>
                  </template>
                  <template v-slot="scope" v-else>
                    <slot v-bind="scope" :name="column.index">
                    </slot>
                  </template>
                </el-table-column>
              </template>
            </el-table>

          </el-scrollbar>
        </div>
        <template #footer>
          <div class="pagination">
            <el-pagination
                background
                :page-sizes="[4, 7, 9, 10]"
                layout="total, sizes, prev, pager, next, jumper"
                :current-page="pageDto.page"
                :page-size="pageDto.size"
                :total="pageTotal"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
            ></el-pagination>
          </div>
          <el-button @click="close">取 消</el-button>
          <el-button type="primary" @click="submitAllSelection(selectForm)">确 定</el-button>
        </template>
      </el-dialog>
      <el-form ref="selectForm" :model="form" label-width="70px" >
        <el-form-item :rules="props.rules" v-if="isShowInput">
          <el-select ref="fuzzySearch" v-model="selectValues" @focus="closeOptions()" @click="open" filterable
                     :multiple="true" placeholder="请选择">
          </el-select>
        </el-form-item>
      </el-form>
    </template>
    <template v-else-if="props.checkType=='single'">
      <el-dialog v-model="visible" width="65%" :fullscreen="true" style="width: 70%" :title="props.title"
                 destroy-on-close
                 :before-close="close">
        <template #header>
          <div class="container" style="padding: 0px">
            <el-row :gutter="10" style="margin-bottom: 15px;">
              <span role="heading" class="el-dialog__title">{{ props.title }}</span>
            </el-row>
            <el-form :model="pageDto" ref="queryForm" :inline="true" v-show="showSearch"
                     label-width="68px">
              <slot v-bind="pageDto" name="pre-exactSearchForm">
                <!--        额外的搜索条件项-->
              </slot>
              <el-form-item v-for="(column,index) in searchformList" :key="index" :label="column.label"
                            :prop="column.index">
                <!--        如果是字典类型-->
                <template v-if="column.type=='dict'">
                  <el-select v-model="pageDto[column.index]"
                             :placeholder="'请选择'+column.label"
                             clearable>
                    <el-option
                        v-for="dict in dict(column.dictkey)"
                        :key="dict.value"
                        :label="dict.label"
                        :value="toStrOrInt(pageDto[column.index],dict.value)"
                    />
                  </el-select>
                </template>
                <template v-else>
                  <el-input
                      v-model="pageDto[column.index]"
                      :type="column.dataType?column.dataType:'text'"
                      :placeholder="'请输入'+column.label"
                      clearable
                      @keyup.enter.native="handleQuery"
                  />
                </template>

              </el-form-item>
              <slot name="exactSearchForm">
                <!--        额外的搜索条件项-->
              </slot>
              <el-form-item>
                <el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
                <el-button icon="RefreshRight" @click="resetQuery">重置</el-button>
              </el-form-item>
            </el-form>
            <el-row :gutter="10" style="margin-bottom: 8px;">
              <right-toolbar v-model:showSearch="showSearch" v-show="props.rightToolbar" @queryTable="handleQuery"
              ></right-toolbar>
            </el-row>
          </div>
        </template>
        <div style="height: 320px">
          <el-scrollbar style="height:100%">
            <el-table
                :data="tableData"
                class="table"
                ref="multipleTable"
                v-loading="listLoading"
                header-cell-class-name="table-header"
                @current-change="handleSingleSelect"
            >
              <template slot="empty">
                <el-empty description="暂无数据"></el-empty>
              </template>
              <el-table-column width="55" align="center">
                <template v-slot="scope">
                  <!-- 可以手动的修改label的值，从而控制选择哪一项 -->
                  <el-radio v-model="radioSelected['keys']" :label="scope.row[props.keys]">{{ '' }}</el-radio>
                </template>
              </el-table-column>
              <template v-for="(column,index) in columns" :key="index">
                <el-table-column :prop="column.index" :width="column.hasOwnProperty('width')?column.width:''"
                                 v-if="column.visible||!column.hasOwnProperty('visible')"
                                 :label="column.label" align="center">
                  <template v-slot="scope" v-if="column.type!='opt'">
                    <template v-if="column.type!='dict'">
                      <slot v-bind="scope" :name="column.index">
                        {{ scope.row[column.index] }}
                      </slot>
                    </template>
                    <template v-else>
                      <dict-tag :options="dict(column.dictkey)" :value="scope.row[column.index]"/>
                    </template>
                  </template>
                  <template v-slot="scope" v-else>
                    <slot v-bind="scope" :name="column.index">
                    </slot>
                  </template>
                </el-table-column>
              </template>
            </el-table>
          </el-scrollbar>
        </div>
        <template #footer>
          <div class="pagination">
            <el-pagination
                background
                :page-sizes="[4, 7, 9, 10]"
                layout="total, sizes, prev, pager, next, jumper"
                :current-page="pageDto.page"
                :page-size="pageDto.size"
                :total="pageTotal"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
            ></el-pagination>
          </div>
          <el-button @click="close">取 消</el-button>
          <el-button type="primary" @click="submitSelection(selectForm)">确 定</el-button>
        </template>
      </el-dialog>
      <el-form ref="selectForm" :model="form" label-width="70px" >
        <el-form-item :rules="props.rules" v-if="isShowInput">
          <el-select ref="fuzzySearch" v-model="radioSelected" @focus="closeOptions()" @click="open" filterable
                      placeholder="请选择">
          </el-select>
        </el-form-item>
      </el-form>
    </template>
  </div>
</template>

<script lang="ts" setup>
import {
  defineProps,
  defineEmits,
  defineExpose,
  ref,
  inject,
  reactive,
  onMounted,
  getCurrentInstance,
  watch,
  computed, toRaw
} from 'vue'
import {ElMessage, ElMessageBox, FormInstance} from "element-plus";
import {deteleAllData, deteleData, ExportData, fetchData, queryPostData, saveorUpadateDate} from "@/api";
import {LoadDict} from "@/utils/dict";
import {useStore} from "vuex";
import {getDtDict} from "@/api/dict";

const props = defineProps({
  tabletype: {
    type: String,
    default: "normal"
  },
  data: {
    type: String
  },
  item: {
    type: Object,
    default: {
      "type": "column",//普通行，字典行，自定义行
      "dictkey": "",//字典key值
      "lable": "",//标签名称
      "index": "",//数据库索引
      "rules": "",//值规则
      "search": "true",//是否是搜索表单
      "visible": "true",//默认可见,
      "dataType": "",//值值类型默认字符类型
      "value": "",//自定义值类型,
      "width": "auto",//宽度
    }
  },
  keys: {
    type: String,
    default: 'id'
  },
  lable: {
    type: String,
    default: 'name'

  },
  checkType: {
    type: String,
    default: 'multiple'//默认多选，single单选
  },
  toolbar: {
    type: Array,
    default: ["add", "del", "upload", "download"]
  },
  listapiurl: {
    type: String,
    default: "list"
  },
  updapiurl: {
    type: String,
    default: "save"
  },
  exportapiurl: {
    type: String,
    default: "export"
  },
  delapiurl: {
    type: String,
    default: "del"
  },
  exportTemplateapiurl: {
    type: String,
    default: "exportTemplate"
  },
  uploadExcelapiurl: {
    type: String,
    default: "uploadExcel"
  },
  columns: {
    type: Array,
  },

  rules: {
    type: Array,
    default: []
  },
  title: {
    type: String,
    default: "表格选择"
  },
  url: {
    type: String, //数据请求地址根路径
    default: "/process/admin/"
  },
  tableName: {  //表名
    type: String,
    default: "",
  },
  isShowInput: {
    type: Boolean,
    default: true,
  },
  rightToolbar: {
    type: Boolean,
    default: true
  },
  visible: {
    type: Boolean,
    default: false,
  },
  value: {
    type: Object,
  },
  queryDataSelf: {
    type: Boolean,
    default: false,
  },
  saveDataSelf: {
    type: Boolean,
    default: false,
  },
  delDataSelf: {
    type: Boolean,
    default: false,
  },



})
let Tool = inject("$Tool")
const store = useStore();
let internalInstance = getCurrentInstance()
let tableData = ref([])
let multipleSelection = reactive([])
let delList = reactive([])
let pageTotal = ref(0)
let showSearch = ref(true)
let listLoading = ref(false)
let form = reactive({})
let searchformList = reactive([])
let showcoulumns = reactive([])
let addcoulumns = reactive([])
let editcoulumns = reactive([])
let fuzzySearch = ref(null)
let idx = ref(-1)
let id = ref(-1)
const pageDto = reactive({
  current: 1,
  size: 10
})

const emit = defineEmits(["update:value","update:visible","submitAll","submit","queryDataFunction","saveDataFunction","delDataFunction"]);
const upload = reactive({
  // 是否显示弹出层（用户导入）
  open: false,
  // 弹出层标题（用户导入）
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 是否更新已经存在的用户数据
  updateSupport: 0,
  // 设置上传的请求头部
  headers: {Authorization: `Bearer ${Tool.getLoginUser().token}`},
  // 上传的地址
  url: props.url + "/" + props.tableName + `/${props.uploadExcelapiurl}`
})
let selectForm = ref<FormInstance>();
let queryForm = ref<FormInstance>();
let selectValues = ref([]) //多选框传值
let radioSelected = ref({}) // 单选框传值
let getData = () => {
  listLoading.value = true
  fetchData(props.url + "/" + props.tableName + `/${props.listapiurl}`, pageDto).then((res: any) => {
    listLoading.value = false
    tableData.value = res.records;
    pageTotal.value = res.total;
  }).finally(() => {
    listLoading.value = false
  });
}
const visible=ref(props.visible)
let readyGetData = () => {
  if (props.queryDataSelf) {
    emit('queryDataFunction',pageDto,(res)=>{
      tableData.value = res.records;
      pageTotal.value = res.total;
    })
  } else {
    getData()
  }
}
let closeOptions = () => {
  fuzzySearch.value.blur()
}

onMounted(async () => {
  let dicts = [];
  for (let columnsKey in props.columns) {
    let item: any = props.columns[columnsKey]
    if (item.type != 'opt') {
      if (item.search) {
        searchformList.push(item);
      }
      if (item.type == 'dict') {
        dicts.push(item.dictkey)
      }
      showcoulumns.push(item)
      if (!item.hasOwnProperty("addable") || item.addable) {
        addcoulumns.push(item)
      }
      if (!item.hasOwnProperty("editable") || item.editable) {
        editcoulumns.push(item)
      }
    }
  }
  LoadDict(dicts);
  readyGetData()
  let value: any = props.value
  let ids = []
  if((value instanceof  Array)){
    ids=value
  }else{
    ids.push(value)
  }
  if (value != undefined && value != '') {
    getDtDict({
      "ids":ids,
      "key":props.keys,
      "lable":props.lable,
      "table":props.tableName
    }).then((res: any) => {
      listLoading.value = false
      for (let i = 0; i < res.length; i++) {
        if(props.checkType=='multiple') {
          selectValues.value.push({keys: res[i][props.keys], label: res[i][props.lable]});
        }else{
          radioSelected.value={keys: res[i][props.keys], label: res[i][props.lable]}
        }
      }
    }).finally(() => {
      listLoading.value = false
    });
  }


})
const dict = computed(() => {
  return function (key: any) {
    var dicts = store.state.dicts.dictMap.get(key);
    if (dicts) {
      return toRaw(dicts.type[key])
    } else {
      return []
    }
  }
})


let handleSizeChange = (size: any) => {
  pageDto.size = size;
  readyGetData()
}
let handleCurrentChange = (page: any) => {
  pageDto.current = page;
  readyGetData()
}

let handleSelectionChange = (val: any) => {
  multipleSelection = val;
}
let submitAllSelection = (formName: any) => {
  formName.validate((valid) => {
        if (valid) {
          const length = multipleSelection.length;
          let ids = [];
          delList = delList.concat(multipleSelection);
          let keys = selectValues.value.map(e => e.keys)
          for (let i = 0; i < length; i++) {
            if (!keys.includes(multipleSelection[i][props.keys])) {
              selectValues.value.push({keys: multipleSelection[i][props.keys], label: multipleSelection[i][props.lable]});
            }
          }
          emit('submitdata',multipleSelection)//对外抛数据（）
          multipleSelection = [];
          close()
          emit('submitAll',selectValues.value)//自定义提交内容(有参数)
          emit('submitAll')//自定义提交内容（）
        }
      }
  )
}

let submitSelection = (formName: any) => {
  formName.validate((valid) => {
        if (valid) {
          close()
          emit('submit',radioSelected.value)//自定义提交内容(有参数)
          emit('submit')//自定义提交内容
        }
      }
  )
}
const handleSingleSelect = (selection: any) => {
  if(selection!=null) {
    debugger
    emit('submitdata',selection)//对外抛数据（）
    radioSelected.value = {keys: selection[props.keys], label: selection[props.lable]}
  }else{
    radioSelected.value={}
  }
}
const toStrOrInt=((formdata:any,item:any)=>{
  return (typeof formdata==='string')?item:parseInt(item)
})
const close = () => {
  emit('update:visible', false)
  visible.value=false
}
const open = () => {
  emit('update:visible', true)
  visible.value=true
}

watch(selectValues, (now, old) => {
  emit('update:value', now.map(e => e['keys']))
}, {deep: true})
watch(radioSelected, (now, old) => {
  emit('update:value', now['keys'])
}, {deep: true})


let handleQuery = () => {
  pageDto.current = 1;
  readyGetData()
}
/** 重置按钮操作 */
let resetForm = (formName: FormInstance | undefined) => {
  if (formName !== undefined) {
    formName.resetFields()
  }
}
/** 重置按钮操作 */
let resetQuery = () => {
  {
    resetForm(queryForm.value);
    handleQuery();
  }
}
let updform = (value: any) => {
  form = reactive(value)
}
defineExpose({
  readyGetData,
  dict,
  form,
  open,
  close
})


</script>
<style scoped>
.handle-box {
  margin-bottom: 20px;
}

.table {
  width: 100%;
  font-size: 14px;
}

.el-dialog {
  margin-bottom: 0;
  height: 100%;
  overflow: auto;
  width: 70% !important;
}

.red {
  color: #ff0000;
}

.hidecolumns {
  display: none;
}

.mr10 {
  margin-right: 10px;
}

.el-form-item .el-form-item {
  margin-bottom: 18px;
}
</style>